{
  "nbformat": 4,
  "nbformat_minor": 0,
  "metadata": {
    "colab": {
      "name": "Neural ODE Basic.ipynb",
      "version": "0.3.2",
      "provenance": [],
      "collapsed_sections": []
    },
    "kernelspec": {
      "name": "python3",
      "display_name": "Python 3"
    },
    "accelerator": "GPU"
  },
  "cells": [
    {
      "cell_type": "code",
      "metadata": {
        "id": "2Fh9sIGm2X7g",
        "colab_type": "code",
        "outputId": "b9f65b36-c369-4e4a-f675-33c4c0da1e73",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 34
        }
      },
      "source": [
        "!git clone https://github.com/rtqichen/torchdiffeq.git"
      ],
      "execution_count": 0,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "fatal: destination path 'torchdiffeq' already exists and is not an empty directory.\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "X86kkneH3YO3",
        "colab_type": "code",
        "outputId": "2091c457-28cb-4873-9b80-1febd74c936e",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 153
        }
      },
      "source": [
        "!cd torchdiffeq && pip install -e ."
      ],
      "execution_count": 0,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "Obtaining file:///content/torchdiffeq\n",
            "Requirement already satisfied: torch>=0.4.1 in /usr/local/lib/python3.6/dist-packages (from torchdiffeq==0.0.1) (1.1.0)\n",
            "Requirement already satisfied: numpy in /usr/local/lib/python3.6/dist-packages (from torch>=0.4.1->torchdiffeq==0.0.1) (1.16.4)\n",
            "Installing collected packages: torchdiffeq\n",
            "  Found existing installation: torchdiffeq 0.0.1\n",
            "    Can't uninstall 'torchdiffeq'. No files were found to uninstall.\n",
            "  Running setup.py develop for torchdiffeq\n",
            "Successfully installed torchdiffeq\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "5SDzjdlr3ZOK",
        "colab_type": "code",
        "outputId": "76fef485-be0c-4fb5-9601-66353af69381",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 34
        }
      },
      "source": [
        "!ls torchdiffeq/torchdiffeq"
      ],
      "execution_count": 0,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "_impl  __init__.py  __pycache__\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "1qN6kVEz3a7v",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "# !wget https://www.dropbox.com/s/wmw93urz7e4mqo5/control_beats_6.npy\n",
        "# beats = np.load('control_beats_6.npy')"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "q6dmtsw_3cMt",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "import os\n",
        "import time\n",
        "import numpy as np\n",
        "import numpy.random as npr\n",
        "import matplotlib.pyplot as plt\n",
        "\n",
        "import torch\n",
        "import torch.nn as nn\n",
        "import torch.optim as optim\n",
        "import torch.nn.functional as F\n",
        "\n",
        "# from torchdiffeq.torchdiffeq import odeint\n",
        "\n",
        "device = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n",
        "\n",
        "from torchdiffeq import odeint"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "6wg7n5aV4tBz",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "batch_time = 10\n",
        "batch_size = 20\n",
        "data_size = 200\n",
        "\n",
        "viz = True"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "0Ig_nh6y4f3H",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "def get_batch():\n",
        "    s = torch.from_numpy(np.random.choice(np.arange(data_size - batch_time, dtype=np.int64), batch_size, replace=False))\n",
        "    batch_y0 = true_y[s]  # (M, D)\n",
        "    batch_t = t[:batch_time]  # (T)\n",
        "    batch_y = torch.stack([true_y[s + i] for i in range(batch_time)], dim=0)  # (T, M, D)\n",
        "    return batch_y0, batch_t, batch_y\n",
        "\n",
        "\n",
        "def makedirs(dirname):\n",
        "    if not os.path.exists(dirname):\n",
        "        os.makedirs(dirname)"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "-E_KQScOSrYj",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "DATA_TYPE = 'NNET_MORE'"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "Jf9zrQne5h1j",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "if viz:\n",
        "    makedirs(DATA_TYPE)\n",
        "    import matplotlib.pyplot as plt\n",
        "\n",
        "def visualize(true_y, pred_y, odefunc, itr):\n",
        "  \n",
        "    if viz:\n",
        "      \n",
        "        plt.figure()\n",
        "        plt.plot(t.numpy(), true_y.numpy()[:, 0, 0], t.numpy(), true_y.numpy()[:, 0, 1], 'g-')\n",
        "        plt.plot(t.numpy(), pred_y.numpy()[:, 0, 0], '--', t.numpy(), pred_y.numpy()[:, 0, 1], 'b--')\n",
        "        plt.savefig(DATA_TYPE + '/ts' + str(itr) + '.png')\n",
        "        plt.show()\n",
        "        \n",
        "        plt.figure()\n",
        "        plt.plot(true_y.numpy()[:, 0, 0], true_y.numpy()[:, 0, 1], 'g-')\n",
        "        plt.plot(pred_y.numpy()[:, 0, 0], pred_y.numpy()[:, 0, 1], 'b--')\n",
        "        plt.savefig(DATA_TYPE + '/phase' + str(itr) + '.png')\n",
        "        plt.show()"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "ObgT2pd54yXw",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "class RunningAverageMeter(object):\n",
        "    \"\"\"Computes and stores the average and current value\"\"\"\n",
        "\n",
        "    def __init__(self, momentum=0.99):\n",
        "        self.momentum = momentum\n",
        "        self.reset()\n",
        "\n",
        "    def reset(self):\n",
        "        self.val = None\n",
        "        self.avg = 0\n",
        "\n",
        "    def update(self, val):\n",
        "        if self.val is None:\n",
        "            self.avg = val\n",
        "        else:\n",
        "            self.avg = self.avg * self.momentum + val * (1 - self.momentum)\n",
        "        self.val = val"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "MYIbsANj8Upx",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "class ODEFunc(nn.Module):\n",
        "\n",
        "    def __init__(self):\n",
        "        super(ODEFunc, self).__init__()\n",
        "\n",
        "        self.net = nn.Sequential(\n",
        "            nn.Linear(2, 50),\n",
        "            nn.Tanh(),\n",
        "            nn.Linear(50, 2),\n",
        "        )\n",
        "\n",
        "        for m in self.net.modules():\n",
        "            if isinstance(m, nn.Linear):\n",
        "                nn.init.normal_(m.weight, mean=0, std=0.1)\n",
        "                nn.init.constant_(m.bias, val=0)\n",
        "\n",
        "    def forward(self, t, y):\n",
        "        return self.net(y)\n"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "73k21V_VEfd-",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "true_y0 = torch.tensor([[1., 1.]])\n",
        "t = torch.linspace(-1., 1., data_size)\n",
        "\n",
        "# true_A = torch.tensor([[-0.1, 2.0], [-2.0, -0.1]])\n",
        "# true_A = torch.randn(2, 2)/2.\n",
        "\n",
        "# a, b, c, d = 1.5, 1.0, 3.0, 1.0\n",
        "# true_A = torch.tensor([[0., -b*c/d], [d*a/b, 0.]])\n",
        "\n",
        "# true_A2 = torch.tensor([[-0.1, -0.5], [0.5, -0.1]])\n",
        "# true_B2 = torch.tensor([[0.2, 1.], [-1, 0.2]])\n",
        "\n",
        "class Lambda(nn.Module):\n",
        "\n",
        "    def forward(self, t, y):\n",
        "        return torch.mm(y, true_A)\n",
        "   \n",
        "      \n",
        "class Lambda2(nn.Module):\n",
        "    \n",
        "    def __init__(self, A, B):\n",
        "        super(Lambda2, self).__init__()\n",
        "        self.A = nn.Linear(2, 2, bias=False)\n",
        "        self.A.weight = nn.Parameter(A)\n",
        "        self.B = nn.Linear(2, 2, bias=False)\n",
        "        self.B.weight = nn.Parameter(B)\n",
        "    \n",
        "    def forward(self, t, y):\n",
        "        xTx0 = torch.sum(y * true_y0, dim=1)\n",
        "        dxdt = torch.sigmoid(xTx0) * self.A(y - true_y0) + torch.sigmoid(-xTx0) * self.B(y + true_y0)\n",
        "        return dxdt\n",
        "      \n",
        "# with torch.no_grad():\n",
        "#     true_y = odeint(Lambda2(true_A2, true_B2), true_y0, t, method='dopri5')\n",
        "    \n",
        "# with torch.no_grad():\n",
        "#     true_y = odeint(Lambda(), true_y0, t, method='dopri5')"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "2Wjyhn6jmPd0",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "true_y0 = torch.tensor([[1., 1.]])\n",
        "t = torch.linspace(-15., 15., data_size)\n",
        "\n",
        "\n",
        "class Lambda3(nn.Module):\n",
        "  \n",
        "    def __init__(self):\n",
        "        super(Lambda3, self).__init__()\n",
        "        self.fc1 = nn.Linear(2, 25, bias = False)\n",
        "        self.fc2 = nn.Linear(25, 50, bias = False)\n",
        "        self.fc3 = nn.Linear(50, 10, bias = False)\n",
        "        self.fc4 = nn.Linear(10, 2, bias = False)\n",
        "        self.relu = nn.ELU(inplace=True)\n",
        "        \n",
        "    def forward(self, t, y):\n",
        "        x = self.relu(self.fc1(y * t))\n",
        "        x = self.relu(self.fc2(x))\n",
        "        x = self.relu(self.fc3(x))\n",
        "        x = self.relu(self.fc4(x))\n",
        "        return x\n",
        "     \n",
        "with torch.no_grad():\n",
        "    true_y = odeint(Lambda3(), true_y0, t, method='dopri5')"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "i6psvwfUqpfy",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "class ODEFunc(nn.Module):\n",
        "\n",
        "    def __init__(self):\n",
        "        super(ODEFunc, self).__init__()\n",
        "\n",
        "        self.net = nn.Sequential(\n",
        "            nn.Linear(2, 150),\n",
        "            nn.Tanh(),\n",
        "            nn.Linear(150, 50),\n",
        "            nn.Tanh(),\n",
        "            nn.Linear(50, 50),\n",
        "            nn.Tanh(),\n",
        "            nn.Linear(50, 2),\n",
        "        )\n",
        "\n",
        "        for m in self.net.modules():\n",
        "            if isinstance(m, nn.Linear):\n",
        "                nn.init.normal_(m.weight, mean=0, std=0.1)\n",
        "                nn.init.constant_(m.bias, val=0)\n",
        "\n",
        "    def forward(self, t, y):\n",
        "        return self.net(y)\n"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "bUYHiVvEXhJY",
        "colab_type": "code",
        "outputId": "c11b710f-e742-4430-8a65-5590aba2b144",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 521
        }
      },
      "source": [
        "plt.figure()\n",
        "plt.plot(t.numpy(), true_y.numpy()[:, 0, 0], t.numpy(), true_y.numpy()[:, 0, 1], 'g-')\n",
        "plt.show()\n",
        "\n",
        "plt.figure()\n",
        "plt.plot(true_y.numpy()[:, 0, 0], true_y.numpy()[:, 0, 1], 'g-')\n",
        "plt.show()"
      ],
      "execution_count": 0,
      "outputs": [
        {
          "output_type": "display_data",
          "data": {
            "image/png": "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\n",
            "text/plain": [
              "<Figure size 432x288 with 1 Axes>"
            ]
          },
          "metadata": {
            "tags": []
          }
        },
        {
          "output_type": "display_data",
          "data": {
            "image/png": "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\nTkSuQmCC\n",
            "text/plain": [
              "<Figure size 432x288 with 1 Axes>"
            ]
          },
          "metadata": {
            "tags": []
          }
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "Huz2sGY85azt",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "  ii = 0\n",
        "  niters = 5000\n",
        "\n",
        "  func = ODEFunc()\n",
        "  optimizer = optim.RMSprop(func.parameters(), lr=1e-3)\n",
        "  end = time.time()\n",
        "\n",
        "  time_meter = RunningAverageMeter(0.97)\n",
        "  loss_meter = RunningAverageMeter(0.97)\n",
        "\n",
        "  for itr in range(1, niters + 1):\n",
        "      optimizer.zero_grad()\n",
        "      batch_y0, batch_t, batch_y = get_batch()\n",
        "      pred_y = odeint(func, batch_y0, batch_t)\n",
        "      loss = torch.mean(torch.abs(pred_y - batch_y))\n",
        "      loss.backward()\n",
        "      optimizer.step()\n",
        "\n",
        "      time_meter.update(time.time() - end)\n",
        "      loss_meter.update(loss.item())\n",
        "\n",
        "      if itr % 50 == 0:\n",
        "          with torch.no_grad():\n",
        "              pred_y = odeint(func, true_y0, t)\n",
        "              loss = torch.mean(torch.abs(pred_y - true_y))\n",
        "              print('Iter {:04d} | Total Loss {:.6f}'.format(itr, loss.item()))\n",
        "              visualize(true_y, pred_y, func, ii)\n",
        "              ii += 1\n",
        "\n",
        "      end = time.time()"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "y2RSZG4_xYhi",
        "colab_type": "code",
        "outputId": "c650796b-d1d3-4b9b-c482-71058e6a0dfc",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 1428
        }
      },
      "source": [
        "# !zip -r /content/VOLTERLOTKA.zip /content/VOLTERLOTKA"
      ],
      "execution_count": 0,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "updating: content/VOLTERLOTKA/ (stored 0%)\n",
            "updating: content/VOLTERLOTKA/ts13.png (deflated 1%)\n",
            "updating: content/VOLTERLOTKA/ts29.png (deflated 1%)\n",
            "updating: content/VOLTERLOTKA/ts9.png (deflated 1%)\n",
            "updating: content/VOLTERLOTKA/ts24.png (deflated 1%)\n",
            "updating: content/VOLTERLOTKA/phase19.png (deflated 2%)\n",
            "updating: content/VOLTERLOTKA/phase37.png (deflated 2%)\n",
            "updating: content/VOLTERLOTKA/phase3.png (deflated 4%)\n",
            "updating: content/VOLTERLOTKA/ts27.png (deflated 1%)\n",
            "updating: content/VOLTERLOTKA/phase10.png (deflated 2%)\n",
            "updating: content/VOLTERLOTKA/ts26.png (deflated 1%)\n",
            "updating: content/VOLTERLOTKA/phase4.png (deflated 2%)\n",
            "updating: content/VOLTERLOTKA/phase2.png (deflated 2%)\n",
            "updating: content/VOLTERLOTKA/ts20.png (deflated 1%)\n",
            "updating: content/VOLTERLOTKA/phase7.png (deflated 2%)\n",
            "updating: content/VOLTERLOTKA/phase35.png (deflated 2%)\n",
            "updating: content/VOLTERLOTKA/phase8.png (deflated 2%)\n",
            "updating: content/VOLTERLOTKA/ts21.png (deflated 1%)\n",
            "updating: content/VOLTERLOTKA/phase22.png (deflated 4%)\n",
            "updating: content/VOLTERLOTKA/phase33.png (deflated 2%)\n",
            "updating: content/VOLTERLOTKA/ts3.png (deflated 1%)\n",
            "updating: content/VOLTERLOTKA/phase34.png (deflated 3%)\n",
            "updating: content/VOLTERLOTKA/ts28.png (deflated 1%)\n",
            "updating: content/VOLTERLOTKA/phase28.png (deflated 2%)\n",
            "updating: content/VOLTERLOTKA/ts35.png (deflated 1%)\n",
            "updating: content/VOLTERLOTKA/phase17.png (deflated 3%)\n",
            "updating: content/VOLTERLOTKA/phase27.png (deflated 2%)\n",
            "updating: content/VOLTERLOTKA/phase30.png (deflated 2%)\n",
            "updating: content/VOLTERLOTKA/ts34.png (deflated 1%)\n",
            "updating: content/VOLTERLOTKA/ts25.png (deflated 1%)\n",
            "updating: content/VOLTERLOTKA/ts23.png (deflated 1%)\n",
            "updating: content/VOLTERLOTKA/ts4.png (deflated 1%)\n",
            "updating: content/VOLTERLOTKA/ts1.png (deflated 1%)\n",
            "updating: content/VOLTERLOTKA/ts0.png (deflated 2%)\n",
            "updating: content/VOLTERLOTKA/ts22.png (deflated 1%)\n",
            "updating: content/VOLTERLOTKA/phase5.png (deflated 2%)\n",
            "updating: content/VOLTERLOTKA/ts19.png (deflated 1%)\n",
            "updating: content/VOLTERLOTKA/phase13.png (deflated 2%)\n",
            "updating: content/VOLTERLOTKA/phase25.png (deflated 2%)\n",
            "updating: content/VOLTERLOTKA/phase18.png (deflated 2%)\n",
            "updating: content/VOLTERLOTKA/ts38.png (deflated 1%)\n",
            "updating: content/VOLTERLOTKA/ts37.png (deflated 1%)\n",
            "updating: content/VOLTERLOTKA/ts10.png (deflated 1%)\n",
            "updating: content/VOLTERLOTKA/phase24.png (deflated 2%)\n",
            "updating: content/VOLTERLOTKA/ts5.png (deflated 1%)\n",
            "updating: content/VOLTERLOTKA/ts30.png (deflated 1%)\n",
            "updating: content/VOLTERLOTKA/phase21.png (deflated 2%)\n",
            "updating: content/VOLTERLOTKA/phase11.png (deflated 2%)\n",
            "updating: content/VOLTERLOTKA/ts2.png (deflated 1%)\n",
            "updating: content/VOLTERLOTKA/phase14.png (deflated 2%)\n",
            "updating: content/VOLTERLOTKA/phase1.png (deflated 2%)\n",
            "updating: content/VOLTERLOTKA/phase39.png (deflated 2%)\n",
            "updating: content/VOLTERLOTKA/phase29.png (deflated 2%)\n",
            "updating: content/VOLTERLOTKA/ts14.png (deflated 1%)\n",
            "updating: content/VOLTERLOTKA/ts12.png (deflated 1%)\n",
            "updating: content/VOLTERLOTKA/ts32.png (deflated 1%)\n",
            "updating: content/VOLTERLOTKA/phase6.png (deflated 4%)\n",
            "updating: content/VOLTERLOTKA/ts18.png (deflated 1%)\n",
            "updating: content/VOLTERLOTKA/phase20.png (deflated 2%)\n",
            "updating: content/VOLTERLOTKA/phase31.png (deflated 2%)\n",
            "updating: content/VOLTERLOTKA/ts11.png (deflated 1%)\n",
            "updating: content/VOLTERLOTKA/phase36.png (deflated 2%)\n",
            "updating: content/VOLTERLOTKA/ts8.png (deflated 1%)\n",
            "updating: content/VOLTERLOTKA/phase16.png (deflated 2%)\n",
            "updating: content/VOLTERLOTKA/phase32.png (deflated 2%)\n",
            "updating: content/VOLTERLOTKA/phase0.png (deflated 3%)\n",
            "updating: content/VOLTERLOTKA/ts16.png (deflated 1%)\n",
            "updating: content/VOLTERLOTKA/phase12.png (deflated 4%)\n",
            "updating: content/VOLTERLOTKA/phase38.png (deflated 4%)\n",
            "updating: content/VOLTERLOTKA/phase23.png (deflated 2%)\n",
            "updating: content/VOLTERLOTKA/ts7.png (deflated 1%)\n",
            "updating: content/VOLTERLOTKA/ts36.png (deflated 1%)\n",
            "updating: content/VOLTERLOTKA/phase9.png (deflated 2%)\n",
            "updating: content/VOLTERLOTKA/ts17.png (deflated 1%)\n",
            "updating: content/VOLTERLOTKA/ts33.png (deflated 1%)\n",
            "updating: content/VOLTERLOTKA/ts31.png (deflated 1%)\n",
            "updating: content/VOLTERLOTKA/phase26.png (deflated 2%)\n",
            "updating: content/VOLTERLOTKA/ts39.png (deflated 1%)\n",
            "updating: content/VOLTERLOTKA/ts15.png (deflated 1%)\n",
            "updating: content/VOLTERLOTKA/phase15.png (deflated 2%)\n",
            "updating: content/VOLTERLOTKA/ts6.png (deflated 1%)\n",
            "updating: content/VOLTERLOTKA/movie_ts.gif (deflated 17%)\n",
            "updating: content/VOLTERLOTKA/movie_phase.gif (deflated 31%)\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "7Rj72H_DUFmP",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "# from google.colab import files"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "5gsoMmPpsucY",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "# files.download(\"/content/AB.zip\")"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "5rtBMnlYv8eW",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "# import imageio\n",
        "# import glob"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "XCMXdIizwDFl",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "# kargs = { 'duration': 0.5 }\n",
        "# PATH = sorted(glob.glob('/content/VOLTERLOTKA/*.png'))\n",
        "\n",
        "# images = []\n",
        "# for filename in PATH:\n",
        "#     if 'ts' in filename:\n",
        "#       images.append(imageio.imread(filename))\n",
        "# imageio.mimsave('/content/VOLTERLOTKA/movie_ts.gif', images, **kargs)\n",
        "\n",
        "# images = []\n",
        "# for filename in PATH:\n",
        "#     if 'phase' in filename:\n",
        "#       images.append(imageio.imread(filename))\n",
        "# imageio.mimsave('/content/VOLTERLOTKA/movie_phase.gif', images, **kargs)"
      ],
      "execution_count": 0,
      "outputs": []
    }
  ]
}